#include <stdio.h>
#include <string.h>
#include <time.h>
#include "mpx_supt.h"
#include "r1.h"

//help
//Parameters: char argument[], the second argument from help command,
//							   used to call specific help functions
//Returns: nothing
//Functions called: none
//This function checks the parameter against possible help files and prints
//the help file desired by the user. If argument is null, prints the general
//help file. If argument does not match known help files, prints an error message.
void help(char argument[], char extra[]){

if(extra[0] == '\0'){	
	if (argument[0] == '\0'){
		paginate("help.txt");
	}
		
	else if(strcmp(argument, "directory\0") == 0){
			paginate("dir.txt");
	}
	else if(strcmp(argument, "date\0") == 0){
			paginate("date.txt");
	}
	else if(strcmp(argument, "version\0") == 0){
			paginate("ver.txt");
	}
	else if(strcmp(argument, "terminate\0") == 0){
			paginate("term.txt");
	}
	else if(strcmp(argument, "clear\0") == 0){
			paginate("clear.txt");
	}
	else if(strcmp(argument, "prompt\0") == 0){
			paginate("prompt.txt");
	}
	else if(strcmp(argument, "create\0") == 0){
		paginate("crtpcb.txt");
	}
	else if(strcmp(argument, "delete\0") == 0){
		paginate("dltpcb.txt");
	}
	else if(strcmp(argument, "block\0") == 0){
		paginate("block.txt");
	}
	else if(strcmp(argument, "unblock\0") == 0){
		paginate("unblck.txt");
	}
	else if(strcmp(argument, "suspend\0") == 0){
		paginate("suspnd.txt");
	}
	else if(strcmp(argument, "resume\0") == 0){
		paginate("resume.txt");
	}
	else if(strcmp(argument, "priority\0") == 0){
		paginate("setprt.txt");
	}
	else if(strcmp(argument, "show\0") == 0){
		paginate("shopcb.txt");
	}
	else if(strcmp(argument, "showall\0") == 0){
		paginate("shoall.txt");
	}
	else if(strcmp(argument, "showr\0") == 0){
		paginate("shordy.txt");
	}
	else if(strcmp(argument, "showb\0") == 0){
		paginate("shoblk.txt");
	}
	else if(strcmp(argument, "showsr\0") == 0){
		paginate("shosr.txt");
	}
	else if(strcmp(argument, "showsb\0") == 0){
		paginate("shosb.txt");
	}
	else if(strcmp(argument, "me\0") == 0){
		printf("No help for you! >:P\n");
	}
	else if(strcmp(argument, "load\0") == 0){
		paginate("load.txt");
	}
	else if(strcmp(argument, "dispatch\0") == 0){
		paginate("dispat.txt");
	}
	else if(strcmp(argument, "kill\0") == 0){
		paginate("kill.txt");
	}
	else{
		//error message, argument did not match known help files
		printf("Incorrect help command, please try again or enter 'help' for help.\n");
	}
}

else{ //there was an extra argument
	printf("The help command cannot use that argument, type 'help' for help\n");
}
}

//paginate - prints out text files 358 characters at at time (a single "page" allows 358 characters
//           on the screen).
//Paramters - char txtfile[] - character array containing the name of the text file to be printed. The name
//            must include the file extension, i.e. "file.txt".
//Returns - nothing
void paginate(char txtfile[]){

 FILE *file;
 int count = 0;
 int in_buff_size = 80;
 char buff_response[80];
                if ((file = fopen(txtfile, "r")) == NULL){
                printf("There was an error opening the help file\n");
                }       
                //print help file one character at a time
                else{
                        int c;
                        while((c = fgetc(file)) != EOF){
                                printf("%c", c);
								count++;
								
								if(count == 415){
									printf("\nEnd of page, press enter to contine to next page.\n");
									sys_req(READ, TERMINAL, buff_response, &in_buff_size);
									//continue printing
									if(*buff_response == '\n'){
										count = 0;
										printf("%c", c);									
									}
									else{
										printf("You didn't press enter. You really should have pressed enter.\n");
										sys_req(READ, TERMINAL, buff_response, &in_buff_size);
									}
								}
                        }
						}
                        printf("\n");
                        //close help file
                        fclose(file);

}

//date
//Parameters: char argument[], the second argument from the date command,
//								used to change the date
//            char extra[], any additional characters beyond the single argument
//Returns: nothing
//Functions called: int check_thirty(int), int check_thirty_one(int), int check_leap(int)
//This function displays the system date with no argument, and changes the date
//if an argument is given in the form MM/DD/YYYY
void date(char argument[], char extra[])
{
	date_rec user_date; //built-in date structure
	int int_month, int_day, int_year; 
	char string_month[3] = "\0";
	char string_day[3] = "\0";
	char string_year[5] = "\0";
	int set_date_error = -1;
	
	////begin valid check ints
		int month_valid = 0;
		int day_valid = 0;
		int year_valid = 0;
	//end valid check ints
	
if(extra[0] == '\0')
{
	if(argument[0] == '\0') //if the user gives no argument then it simply prints the current date
	{
		sys_get_date(&user_date);
		printf("Today is %d/%d/%d\n", user_date.month, user_date.day, user_date.year);	
	}
	//this checks basic structure of the date input for slash position and length
	else if((argument[2] == '/' && argument[5] == '/') && (argument[10] == '\n' || argument[10] =='\0'))
	{
		strncpy(string_month, argument, 2); //takes the month from the input
		strncpy(string_day, argument + 3, 2); //takes the day from the input
		strncpy(string_year, argument + 6, 4); //takes the year from the input
		int_month = atoi(string_month); //converts the string month to an integer
		int_day = atoi(string_day); //converts the string day to an integer
		int_year = atoi(string_year); //converts the string year to an integer
		
		if((int_month >= 1) && (int_month <= 12)) //checks if the month is valid
			month_valid = 1;
		if (int_day > 0) // checks if day is real
			day_valid = 1;
		if (int_year > 0) // checks if year is real
			year_valid = 1;
		if ((month_valid + day_valid + year_valid) == 3)
		{
			switch (int_month) {
				case 1:
					day_valid = check_thirty_one(int_day);
					break;
				case 2:
					day_valid = check_leap(int_day, int_year);
					break;
				case 3:
					day_valid = check_thirty_one(int_day);
					break;
				case 4:
					day_valid = check_thirty(int_day);
					break;
				case 5:
					day_valid = check_thirty_one(int_day);
					break;
				case 6:
					day_valid = check_thirty(int_day);
					break;
				case 7:
					day_valid = check_thirty_one(int_day);
					break;
				case 8:
					day_valid = check_thirty_one(int_day);
					break;
				case 9:
					day_valid = check_thirty(int_day);
					break;
				case 10:
					day_valid = check_thirty_one(int_day);
					break;
				case 11:
					day_valid = check_thirty(int_day);
					break;
				case 12:
					day_valid = check_thirty_one(int_day);
					break;
			}
			if (day_valid == 1)
			{
				//set date
				user_date.month = int_month;
				user_date.day = int_day;
				user_date.year = int_year;
				set_date_error = sys_set_date(&user_date);
				if(set_date_error != 0)
				{
					printf("The date was not set properly error:%d\n", set_date_error);
				}
				printf("The date was set to %d/%d/%d\n", user_date.month, user_date.day, user_date.year);
			}
			else
			{
				printf("You have entered an incorrect date, please try again or type 'help' for help.\n");
			}
			
		}
		else
		{
			printf("You have entered an incorrect date, please try again or type 'help' for help.\n");
		}
	}
	else
	{
		printf("You have entered an incorrect date, please try again or type 'help' for help.\n");
	}
}
else // there was an extra argument
{
	printf("The date fuction cannot use that argument, type 'help' for help\n");
}	
}
//Parameters: int day, the number of days given for the month
//Returns: either 0 or 1 (see below)
//Functions called: none
//Checks that the int paramater is less than or equal to 30. Returns 1 if true, 0 if
//false. Used to check the number of days given for months that should have 30 days.
int check_thirty(int day) {
	int result = 0;
	if (day <= 30)
		result = 1;
	return result;
}

//Parameters: int day, the number of days given for the month
//Returns: either 0 or 1 (see below)
//Functions called: none
//Checks that the int paramater is less than or equal to 31. Returns 1 if true, 0 if
//false. Used to check the number of days given for months that should have 31 days.
int check_thirty_one(int day) {
	int result = 0;
	if (day <= 31)
		result = 1;
	return result;
}
//Parameters: int day, the number of days given for the month
//			  int year, the year given
//Returns: either 0 or 1 (see below)
//Functions called: none
//Checks that the day parameter is consistent with a valid day for February. If
//the year determines it to be a leap year, the day must be less than or equal to
//29.  Otherwise, it must be less than or equal to 28. If these are satisfied,
//1 is returned. Otherwise, 0 is returned.
int check_leap(int day, int year) {
	int result = 0;
	if ((year % 4) == 0) {//might be a leap year
		if ((year % 100) != 0) {//is a leap year - not divisible by 100
			if (day <= 29)
				result = 1;
		}
		else if ((year % 400) == 0) {//is a leap year - divisible by 100 and 400
			if (day <= 29)
				result = 1;
		}
		else {//not a leap year - divisible by 100 but not 400
			if (day <= 28)
				result = 1;
		}
	}
	else {//not a leap year
		if (day <= 28)
			result = 1;
	}
	return result;
}

//Parameters: char extra[], any characters beyond the command (no args permitted)
//Returns: nothing
//Functions called: void terminate_confirmed(void)
//Prompts the user to verify if they wish to terminate, and then either returns without
//terminating if the first character input is 'n' or exits MPX if it is 'y'
void terminate(char extra[]) {
if(extra[0] == '\0'){
	int in_buff_size = 80;
	char buff_response[80];
	//prompt the user to confirm the termination
	printf("Are you sure you wish to terminate MPX? (y/n)\n");
	sys_req(READ, TERMINAL, buff_response, &in_buff_size);
	//read characters, if first is 'y' terminate, else return
	if (*buff_response == 'y')
		terminate_confirmed();
	return;
}
else{ //there was an extra argument
	printf("The terminate function cannot use that argument, type 'help for help\n");
}
}

//Parameters: char extra[], any characters beyond the command (no args permitted)
//Returns: nothing
//Functions called: none
//Displays the version and modified date for MPX
void version(char extra[]) {
if(extra[0] == '\0'){
	//display version and date modified values
	printf("Running MPX version %.1f", MPX_CURRENT_VERSION);
	printf(", last modified on %s\n", MPX_MODIFIED_DATE);
	return;
}
else{ //there was an extra argument
printf("The version function cannot use that argument, type 'help' for help\n");
}
}

//Parameters: none
//Returns: nothing
//Functions called: void terminate_cleanup(void)
//Handles the MPX exit proceedure when the user confirms the termination.
//Calls terminate_cleanup for final memory and state handling
void terminate_confirmed() {
	printf("MPX is terminating");
	sleep(1);
	printf(".");
	sleep(1);
	printf(".");
	sleep(1);
	printf(".\n");
	printf("Goodbye!\n");
	//for future use in memory/state management on exit
	terminate_cleanup();
	sys_req(CLEAR, TERMINAL, 0, 0);
	sys_exit();
}

//Parameters: char argument[] determines if a path name was typed in
//				char extra[]  used to determine if too many arguments were given 
//Returns: nothing
//Functions called: sys_open_dir
//					sys_get_entry
//					sys_close_dir
//  From the command line, enter "directory" to display the content of the
//  current directory.  To display the content of a directory other
//  than the current one, add a single space and then the exact path
//  name after the command.
//

void directory (char argument[], char extra[])
{
if(extra[0] == '\0'){

//int buffLen = 10;
int cC = 20;
char ret_buffer[20];
long sizeOr = 999;
int sys_open_dir_error = -1;
int sys_get_entry_error = -1;

	sys_open_dir_error = sys_open_dir(argument);

	if (sys_open_dir_error != 0){
      printf("There was a problem with sys_open_dir, error %s\n", sys_open_dir_error);
	}
	else{
		do{
		sys_get_entry_error = sys_get_entry(ret_buffer, cC, &sizeOr);
		if(sys_get_entry_error == ERR_SUP_NOENTR){
			printf("There are no more files in the directory\n");
		}
		else if (sys_get_entry_error == 0){
			printf("%s\t%d B\n", ret_buffer, sizeOr);
		}
		else{
			printf("There was a problem with sys_get_enrty, error %s\n", sys_get_entry_error);
		}
        } while (sys_get_entry_error != ERR_SUP_NOENTR);
    }
    sys_close_dir();
}
else //There was an extra arguemnt
{
	printf("The directory command cannot use that argument, type 'help' for help\n");
}
}